\ 15May93 DBH Change echovec per mrh. Separate TEScroller and TEwind code \ into different files. Implement lineEnd: method in intepret: \ 14May93 DBH Dropped new: and test: methods. \ Added enable: and disable: methods \ Reworked interpret: to eliminate local variables. \ Made theTEScroller an ivar. Lock: and unlock: buffer in interpret: \ 11May93 DBH NewEventLoop -> quitvec. \ Handle tabs as 4 spaces. Make code independent of QEinit file. \ 19May93 mrh Made theTEscroller a subview. Added theStack. \ Sept93 mrh revised for new controls scheme. \ Mar94 mrh adapted for TWstr (buffer for output to TW). Added INITFONT \ to DS: in StackView. \ Oct 97 mrh updated for PowerMops. need TEScroller \ need alert TEscroller theTEscroller : TESizeCheck ( n -- ) \ The 2.4 alert was too much of a pest. Now 32000 > \ we just quietly delete some text from the \ front. IF 0 2000 setSelect: theTEscroller clear: theTEscroller 32000 dup setSelect: theTEscroller THEN ; \ support for interpretation \ Note: attempting to handle comments by catching '\' causes problems, \ since '\' can appear in a number of other situations, including \ named parm specifications and quoted strings. Best to just not \ handle '\' - type comments when interpreting from the Mops window. \ : skip_line \ 13 chsearch: QEstr \ negate more: QEstr \ delete: QEstr nolim: QEstr ; : skip1 1 skip: QEstr ; : special>bl reset: QEstr BEGIN len: QEstr WHILE 1st: QEstr 0 31 within? nip IF 32 chovwr: QEstr ELSE skip1 THEN REPEAT reset: QEstr ; \ StackView is a view which just displays the top few stack cells. \ A possible problem is that at the time of call, Mops may have a \ variable number of its own quantities on the stack, depending on the \ circumstances of the call. We avoid this by defining the standard \ DRAW: method to do nothing, and actually do the drawing at regular \ intervals on an idle event, which generally has the same number of \ Mops' quantities on the stack (currently 2). We do a few tricks to \ avoid unnecessary drawing so the view doesn't flicker too much. We \ only draw if the depth has changed since the last idle, or if the \ value drawStack? has been set true, which happens when we interpret \ something (and we set it back false ready for next time). 0 value lastDepth 0 value idleCnt false value drawStack? : EvalFromQE \ Evaluates contents of QEstr. special>bl true -> drawStack? \ Set stack display to draw on next idle lock: QEstr get: QEstr evaluate unlock: QEstr prompt? fWind? or IF ok THEN prompt? IF cr THEN \ prompt & cr if required ; : .S+ -curs ." Stack: " depth 0< IF ." underflow" EXIT THEN depth NIF ." empty" EXIT THEN ." depth " depth . cr sp@ depth 1- FOR dup .cell cr 4+ NEXT drop ; :class STACKVIEW super{ view } :m DS: { \ svPort -- } \ Does the main work for DRAWSTACK:. \ First, if it's time to draw the stack, we make sure we've flushed \ any pending output in the main view. flush_TWstr \ Now let's draw that stack... pushPort -> svPort \ Port could be anything, so we have to get: ^myWind set: class_as> window \ save and restore initFont \ Ensure font is right depth -> lastDepth oldVecs get: viewRect swap 15 - swap put: tempRect draw: tempRect \ Draw a frame 1 1 inset: tempRect addr: tempRect ClipRect clear: tempRect 10 10 gotoxy .s+ [ ppc? ] [if] \ getbotx: tempRect 2/ negate 0 setOrigin \ 10 10 gotoxy ." FP stack: " f.s+ \ 0 0 setOrigin [then] \ include FP stack if on PPC newVecs noClip \ Easier than saving and restoring! svPort popPort ;m :m DRAW: true -> drawStack? ;m :m DRAWSTACK: { x1 -- x1 } \ 30Apr94 DBH, one less stack item to manage. clrStk? IF \ We've been told to clear the stack, so we do it, \ draw it, then get out. sp0 sp! [ ppc? ] [if] depth FOR drop NEXT \ on PPC, resetting the stack \ pointer won't empty the stack! [then] ds: self false -> clrStk? x1 EXIT THEN idleCnt NIF 5 -> idleCnt ELSE 1 --> idleCnt THEN depth lastDepth <> idleCnt 0= and \ draw if it's time and depth is difft drawStack? or false -> drawStack? \ but if we're told, we draw anyway NIF x1 EXIT THEN ds: self x1 ;m :m IDLE: drawStack: self ;m :m CLASSINIT: parLeft parTop parRight parTop setJust: self 0 0 0 100 setBounds: self ;m ;class stackView theStack :class TEFview super{ view } \ For the TEFwind ContView :m CLASSINIT: classinit: super parLeft parTop parRight parBottom setJust: theTEscroller 0 102 0 0 setBounds: theTEscroller ;m ;class TEFview TFV \ This will be the ContView \ ============= Here's the main TEFwind class =================== :class TEFwind super{ window+ } handle BUFFER \ merely a place to manipulate the TEscrap handle :m CUT: cut: theTEscroller fixPanRect: theTEscroller caretIntoView: theTEscroller ;m :m COPY: copy: theTEscroller ;m :m PASTE: TEScrapHandle put: buffer size: buffer size: theTEScroller + TESizeCheck paste: theTEscroller fixPanRect: theTEscroller caretIntoView: theTEscroller ;m :m CLEAR: clear: theTEscroller fixPanRect: theTEscroller caretIntoView: theTEscroller ;m :m SelAll: 0 32767 setSelect: theTEscroller ;m :m INSERT: { addr len -- } size: theTEscroller len + TESizeCheck addr len insert: theTEscroller ;m :m INTERPRET: { \ echoCR? -- } selEnd: theTEscroller selStart: theTEscroller = IF \ nothing selected getLine: theTEscroller ( addr len ) put: QEstr true -> echoCR? ELSE \ we have a hilited selection handle: theTEscroller TECopy TEScrapHandle put: buffer lock: buffer ptr: buffer size: buffer ( addr len ) put: QEstr unlock: buffer false -> echoCR? THEN lineEnd: theTEscroller dup setselect: theTEscroller echoCR? IF cr THEN evalFromQE flush_TWstr ;m :m KEY: \ ( char -- ) doing_key? IF drop EXIT THEN \ KEY is handling it - we \ mustn't do anything here CASE[ 3 ( enter ) ]=> interpret: self [ 8 ( delete ) ]=> 8 key: theTEscroller \ delete [ 9 ( tab ) ]=> 4 spaces DEFAULT=> size: theTEscroller 1+ TESizeCheck key: theTEscroller ]CASE ;m :m ENABLE: enable: super newVecs ;m :m DISABLE: disable: super ;m :m DRAW: ds: theStack (draw): super ;m \ :m IDLE: idle: super ;m :m TextHandle: textHandle: theTEscroller ;m :m DUMP: dump: theTEscroller ;m ;class handle tmpHndl file WorksheetFile 0 value ^TW : SAVEWORKSHEET " Worksheet" name: worksheetFile 'type TEXT 'type MSET set: worksheetfile create: worksheetFile ?EXIT \ If we're on a network, this \ may fail, so we just get out. textHandle: [ ^TW ] put: tmpHndl lock: tmpHndl ptr: tmpHndl size: tmpHndl write: worksheetFile drop release: tmpHndl close: worksheetFile drop ; : GETWORKSHEET { \ adr n -- } " Worksheet" name: worksheetFile open: worksheetFile IF .room EXIT THEN \ If it doesn't exist, we'll start a \ new one with a .room display, and out. size: worksheetFile -> n n new: tmpHndl lock: tmpHndl ptr: tmpHndl -> adr adr n read: worksheetFile dup -39 = if drop 0 then OK? \ We don't worry if the error \ was endfile bytesRead: worksheetFile -> n close: worksheetFile drop adr n insert: [ ^TW ] release: tmpHndl ; : DO_RUN_TE { TW-addr \ ^view left top rt bot sRt sBot -- } -curs -echo TW-addr -> ^TW deep_classinit: [ ^TW ] \ fWind? IF close: fWind THEN \ say goodbye to Mr. fwind theStack addView: TFV theTEscroller addView: TFV \ pause pause pause \ Get us to the front under sys 6 \ or the system clobbers scroll bars 20 -> left 50 -> top 520 -> rt 360 -> bot screenbits -> sBot -> sRt 2drop rt sRt min -> rt bot sBot min -> bot left top rt bot put: tempRect screenbits true setGrow: [ ^TW ] screenbits true setDrag: [ ^TW ] true setZoom: [ ^TW ] true setColor: [ ^TW ] \ is this OK? tempRect myDoc docWind true false TFV new: [ ^TW ] true focus: theTEScroller newvecs true -> emit? \ EMIT is now safe since we have a window \ true -> relocChk? xts{ xUndo null xCut xCopy xPaste xClear xSelAll null doPref } 3 init: EditMen getworksheet false -> fWindActive? \ Mustn't forget this!! \ eventLoop QUIT ; : BYE+ saveWorksheet bye ; : xCut cut: [ ^TW ] ; : xCopy copy: [ ^TW ] ; : xPaste paste: [ ^TW ] ; : xClear clear: [ ^TW ] ; : xUndo nimpl ; : xSelAll selAll: [ ^TW ] ; endload